<template>
	<view>
		<view class="content" @touchstart="hideEmoji">
			<scroll-view class="msg-list" scroll-y="true" :scroll-with-animation="scrollAnimation" :scroll-top="scrollTop"
			 :scroll-into-view="scrollToView">
				<view class="row" v-for="(row,index) in msgList" :key="index" :id="'msg'+row.id">
					<!-- 自己发出的消息 -->
					<view class="my" v-if="row.uid==myuid">
						<view class="left">
							<view v-if="row.type=='text'" class="bubble">
								<rich-text :nodes="row.msg.content"></rich-text>
							</view>
							<view v-if="row.type=='voice'" class="bubble voice" @tap="playVoice(row)" :class="playMsgid == row.id?'play':''">
								<view class="length">{{row.msg.length}}</view>
								<view class="icon my-voice"></view>
							</view>
							<view v-if="row.type=='img'" class="bubble img" @tap="showPic(row)">
								<image :src="row.msg.url" mode='widthFix' ></image>
							</view>
						</view>
						<view class="right">
							<image :src="row.face"></image>
						</view>
					</view>
					<!-- 别人发出的消息 -->
					<view class="other" v-if="row.uid!=myuid">
						<view class="left">
							<image :src="row.face"></image>
						</view>
						<view class="right">
							<view class="username">
								<view class="name">{{row.username}}</view>
								<!-- <view class="time">{{row.time}}</view> -->
							</view>
							<view v-if="row.type=='text'" class="bubble">
								<rich-text :nodes="row.msg.content"></rich-text>
							</view>
							<view v-if="row.type=='img'" class="bubble img" @tap="showPic(row)">
								<image :src="row.msg.url" mode='widthFix' ></image>
							</view>
						</view>
					</view>
				</view>
			</scroll-view>
		</view>
		<!-- 表情栏 -->
		<view class="emoji-box" :class="showEmji"  @touchmove.stop.prevent="discard">
			<swiper class="swiper" indicator-dots="true" duration="150">
				<swiper-item v-for="(page,pid) in emojiList2" :key="pid">
					<view v-for="(em,eid) in page" :key="eid" @tap="addEmoji(em)">
						<image mode="widthFix" :src=" reqUrl+'public/dist/images/face/'+em.url"></image>
					</view>
				</swiper-item>
			</swiper>
		</view>
		<!-- 底部输入栏 -->
		<view class="input-box" :class="showEmji" @touchmove.stop.prevent="discard">
			<view class="more" @tap="chooseImage">
				<view class="icon tupian"></view>
			</view>
			<view class="textbox">
				<view class="text-mode" :class="isVoice?'hidden':''">
					<view class="box">
						<textarea auto-height="true" v-model="textMsg" id="textMsg" />
					</view>
					<view class="em" @tap="chooseEmoji">
						<view class="icon biaoqing"></view>
					</view>
				</view>
			</view>
			<label for="textMsg">
			<view class="send" :class="isVoice?'hidden':''" @tap="sendText">
				<view class="btn">发送</view>
			</view>
			</label>
		</view>
	</view>
</template>

<script>
	import config from '../../config/config'
	//#ifdef H5 
		import lrz from '../../static/js/lrz.bundle'
	//#endif
	import { mapState,mapMutations } from 'vuex'
	export default {
		data() {
			return {
				reqUrl:(config.debug == true ? config.debugUrl:config.serverUrl).replace('index.php/',''),
				order_no:"",
				//文字消息
				textMsg:'',
				//消息列表
				scrollAnimation:false,
				scrollTop:0,
				scrollToView:'',
				msgList:[],
				msgImgList:[],
				myuid:0,
				sendid:0,
				//录音相关参数
				// #ifndef H5
				//H5不能录音
				RECORDER:uni.getRecorderManager(),
				// #endif
				isVoice:false,
				voiceTis:'按住 说话',
				recordTis:"手指上滑 取消发送",
				recording:false,
				willStop:false,
				initPoint:{identifier:0,Y:0},
				recordTimer:null,
				recordLength:0,
				//播放语音相关参数
				AUDIO:uni.createInnerAudioContext(),
				playMsgid:null,
				VoiceTimer:null,
				//表情定义
				showEmji:'',
				emojiList:[],
				emojiList2:[]
			};
		},
		computed: mapState(['forcedLogin', 'hasLogin', 'userInfo']),
		onLoad(option) {
			this.myuid = this.userInfo.user_guid;
			this.sendid = option.uid;
			this.order_no = option.order_no;
			uni.setNavigationBarTitle({ title: '客服' || option.name || '客服' });
			this.getCache();
			this.webSocket();
			this.initEmojiList();
		},
		methods:{
			...mapMutations(['setCsdMsgChatList']),
			// 初始化表情
			initEmojiList(){
				let alts = [
					"[微笑]", "[嘻嘻]", "[哈哈]", "[可爱]", "[可怜]", "[挖鼻]", "[吃惊]", "[害羞]", 
					"[挤眼]", "[闭嘴]", "[鄙视]", "[爱你]", "[泪]","[偷笑]", "[亲亲]", "[生病]", 
					"[太开心]", "[白眼]", "[右哼哼]", "[左哼哼]", "[嘘]","[衰]", "[委屈]", "[吐]", 
					"[哈欠]", "[抱抱]", "[怒]", "[疑问]", "[馋嘴]","[拜拜]", "[思考]", "[汗]", "[困]",
					"[睡]", "[钱]", "[失望]", "[酷]", "[色]", "[哼]", "[鼓掌]", "[晕]", "[悲伤]", 
					"[抓狂]", "[黑线]", "[阴险]","[怒骂]", "[互粉]", "[心]", "[伤心]", "[猪头]", 
					"[熊猫]", "[兔子]", "[ok]", "[耶]", "[good]", "[NO]", "[赞]", "[来]", "[弱]", 
					"[草泥马]", "[神马]", "[囧]","[浮云]", "[给力]", "[围观]", "[威武]", "[奥特曼]",
					"[礼物]", "[钟]", "[话筒]","[蜡烛]", "[蛋糕]"
				];
				let	emojiList = [];
				let	emojiList2 = [[],[],[]];
				for(let i=0;i<alts.length;i++){
					let obj = {"url":i + ".gif",alt:alts[i]};
					emojiList.push(obj);
					if(i<24){ emojiList2[0].push(obj); }
					if(i>24 && i<49){ emojiList2[1].push(obj); }
					if(i>49 && i<74){ emojiList2[2].push(obj); }
				}
				this.emojiList = emojiList;
				this.emojiList2 = emojiList2;
			},
			//获取消息列表
			getCache(){
				var that = this;
				that.$request("/common/app_csd/getCache",{
					send_id:that.sendid || "",
					order_no:that.order_no || ""
				}).then(res=>{
					let data = res.data;
					let sendid = "";
					let list= (data || []).map(function(h){
						if(h.send_id && h.send_id != that.myuid ) sendid = h.send_id;
						return that.infoConversion(h);
					});
					that.sendid = that.sendid ? that.sendid : sendid;
					// 获取消息中的图片,并处理显示尺寸
					for(let i=0;i<list.length;i++){
						if(list[i].type=='img'){
							list[i] = that.setPicSize(list[i]);
							that.msgImgList.push(list[i].msg.url);
						}
					}
					that.msgList = list;
					// 滚动到底部
					that.$nextTick(function() {
						that.scrollTop = 9999;
						that.scrollAnimation = false;
					});
				});
			},
			// 发送消息
			sendMsg(content,type,src){
				let that = this;
				let contents = this.textMsg;
				if(type=="img"){
					contents="img["+src+"]";
				}
				let param = {
					"send_id":that.myuid,
					"sign" : "",
					"username": that.userInfo.user_name,
					"avatar" : that.userInfo.headimgurl,
					"content" : contents,
					"type" : "friend",
					"order_no":that.order_no || "",
					"recive_id" : that.sendid || "",
					"id" : that.myuid
				};
				that.$request("/common/app_csd/sendMsg",param).then(res=>{
					let nowDate = new Date;
					let msg = {
						id:res.data,
						uid:that.myuid,
						username:param.username,
						face: param.avatar,
						time:nowDate.getHours()+":"+nowDate.getMinutes(),
						type:type,
						msg:content,
					};
					this.screenMsg(msg);
				});
			},
			// Web Socket 连接
			webSocket(){
				var that = this;
				uni.connectSocket({ url: config.webSocketUrl });
				uni.onSocketOpen(function (res) {
					uni.sendSocketMessage({
					  data: JSON.stringify({ type:"reg",mine:{id:that.myuid}})
					});
				});
				uni.onSocketMessage(function (res) {
					var data = JSON.parse(res.data);
					var msg = data.data;
					if(data.type == 'msg'){
						that.sendid = msg.send_id;
						that.screenMsg( that.infoConversion(msg) );
						// 更新信息状态
						if(that.$route.path == '/pages/msg/chat/chat'){
							that.$request("/common/app_csd/updateInfoStatus",{
								send_id:that.sendid,
								status:2
							},false);
						}
					}
					if(data.type == 'getChatList'){
						that.$request("/common/app_csd/getChatList",{},false).then(res=>{
							let data = res.data;
							let chatList = (data || []).map(function(h){
								return {
									uid:h.user_guid,
									username:h.username,
									img: h.img,
									time:h.time,
									msg: h.content,
									tis_num:h.tis_num
								}
							});
							that.setCsdMsgChatList(chatList);
						});
					}
				});
				uni.onSocketError(function (res) {
					console.log('WebSocket连接打开失败，请检查！');
				});
			},
			// 信息转换
			infoConversion(h){
				let type = "text";
				let content = h.content.replace(/face/g, "");
				let nowDate = new Date;
				if(content.indexOf("img[") != -1){ 
					type = 'img'; 
					content = content.replace(/img\[/g, "").replace(/]/g, "");
				}
				if(content.indexOf("file(") != -1){
					type = 'img'; 
					content = content.replace(/file\(/g, "").replace(/\)\[下载文件\]/g, "");
				}
				if(content.indexOf("video[") != -1){
					type = 'voice'; 
					content = content.replace(/video\[/g, "").replace(/]/g, "");
				}
				return {
					id:h.id || 0,
					uid: h.send_id,
					username:h.username,
					face: h.img || h.avatar,
					time:h.time || (nowDate.getHours()+":"+nowDate.getMinutes()),
					type:type,//text,img,voice
					msg:{
						content: this.replaceEmoji(content),
						url:content,
						length:"00:00"
					}
				}
			},
			//处理图片尺寸，如果不处理宽高，新进入页面加载图片时候会闪
			setPicSize(row){
				let maxW = uni.upx2px(350);
				let maxH = uni.upx2px(350);
				if(row.msg.w>maxW||row.msg.h>maxH){
					let scale = row.msg.w/row.msg.h;
					if(row.msg.w>row.msg.h){
						row.msg.w = maxW;
						row.msg.h = row.msg.w/scale
					}else{
						row.msg.h = maxH;
						row.msg.w = row.msg.h*scale;
					}
				}
				return row;
			},
			// 接受消息(筛选处理)
			screenMsg(msg){
				//从长连接处转发给这个方法，进行筛选处理
				if(msg.uid!=this.myuid){
					uni.vibrateLong();
				}
				switch (msg.type){
					case 'text':
						this.addTextMsg(msg);
						break;
					case 'voice':
						this.addVoiceMsg(msg);
						break;
					case 'img':
						this.addImgMsg(msg);
						break;
				}
				this.$nextTick(function() {
					this.scrollToView = 'msg'+msg.id
				});
				this.$nextTick(function() {
					this.scrollTop = 19999;
					this.scrollAnimation = false;
				});
			},
			// 选择表情
			chooseEmoji(){
				this.showEmji = this.showEmji=='showEmoji'?'hideEmoji':'showEmoji';
			},
			// 隐藏表情
			hideEmoji(){
				this.showEmji = this.showEmji=='showEmoji'?'hideEmoji':'';
			},
			//添加表情
			addEmoji(em){
				this.textMsg+= em.alt;
			},
			// 发送文字消息
			sendText(){
				this.hideEmoji();
				if(!this.textMsg){
					return;
				}
				let content = this.replaceEmoji(this.textMsg.replace(/face/g, ""));
				let msg = {content:content}
				this.sendMsg(msg,'text');
				this.textMsg = '';
			},
			//替换表情符号为图片
			replaceEmoji(str){
				let replacedStr = str.replace(/\[([^(\]|\[)]*)\]/g,(item, index)=>{
					for(let i=0;i<this.emojiList.length;i++){
						let row = this.emojiList[i];
						if(row['alt']==item){
							return '<img src="'+this.reqUrl+'/public/dist/images/face/'+row['url']+'"/>';
						}
					}
				});
				return '<div style="display: flex;align-items: center;">'+(replacedStr || "")+'</div>';
			},
			// 选择图片发送
			chooseImage(){
				let that = this;
				this.hideEmoji();
				uni.chooseImage({
					sizeType: ['compressed'], //可以指定是原图还是压缩图，默认二者都有
					success: (res)=>{
						const tempFilePaths = res.tempFilePaths;					
						//压缩宽度
						//#ifdef H5 
						lrz(res.tempFiles[0], {width:350}).then(function (rst) { 
							let file = new File([rst.file], rst.origin.name, {
								type: rst.origin.type, 
								lastModified: Date.now()
							});
							that.uploadFile(tempFilePaths,file);
						}).catch(function (err) {//压缩失败的话 按原图上传
						    that.uploadFile(tempFilePaths,res.tempFiles[0]);
						});
						//#endif
						//#ifndef H5 
							that.uploadFile(tempFilePaths,1);
						//#endif
					}
				});
			},
			// 上传
			uploadFile(paths,file){
				let that = this;
				uni.showLoading({ title: '', mask:true});
				let obj = {
					url:(config.debug == true ? config.debugUrl:config.serverUrl)+'/app/soft/upload/upload',
					header: {
						'authorization': uni.getStorageSync('access_token'),
					},
					formData: {
					   'fkGuid': '00000000-0000-0000-0000-000000000000',
					   'ywName': '客服信息',
					   'fkType': '图片'
					},
					success: function (uploadFileRes) {
						uni.hideLoading();
						let data = JSON.parse(uploadFileRes.data);
						uni.getImageInfo({
							src: paths[0],
							success: (image)=>{
								that.sendMsg({url:paths[0]},'img',data.data.src);
							}
						});
					},
					fail:function(res) {
						uni.hideLoading();
						uni.showToast({icon: 'none',title: '请求异常！'});
					}
				};
				if(file == 1){
					obj.filePath = paths[0];
					obj.name="file";
				}else{
					obj.file=file;
				}
				uni.uploadFile(obj);
			},
			// 处理文字消息
			addTextMsg(msg){
				this.msgList.push(msg);
			},
			// 处理语音消息
			addVoiceMsg(msg){
				this.msgList.push(msg);
			},
			// 处理图片消息
			addImgMsg(msg){
				msg = this.setPicSize(msg);
				this.msgImgList.push(msg.msg.url);
				this.msgList.push(msg);
			},
			// 预览图片
			showPic(row){
				uni.previewImage({
					indicator:"none",
					current:row.msg.url,
					urls: this.msgImgList
				});
			},
			discard(){
				return;
			}
		}
	}
</script>

<style lang="scss">
page{
	background-color: #ffffff;
}
.icon {
	font-size:56upx;
	color: #333;
}
.hidden{
	display: none !important;
}
@keyframes showEM {
	0% {transform: translateY(0);}
	100% {transform: translateY(-42vw);}
}
@keyframes hideEM {
	0% {transform: translateY(-42vw);}
	100% {transform: translateY(0);}
}
.emoji-box{
	&.hideEmoji{animation: hideEM .15s linear both;}
	&.showEmoji{animation: showEM .15s linear both;}
	width: 96%;
	height: 42vw;
	padding: 20upx 2%;
	background-color: #f3f3f3;
	border-top: solid 1upx #ddd;
	position: fixed;
	z-index: 20;
	top: 100%;
	.swiper{
		swiper-item{
			display: flex;
			flex-wrap: wrap;
			view{
				width: 12vw;
				height: 12vw;
				display: flex;
				justify-content: center;
				image{
					width: 60%;
				}
			}
		}
	}
}
.input-box{
	&.hideEmoji{animation: hideEM .15s linear both;}
	&.showEmoji{animation: showEM .15s linear both;}
	width: 98%;
	min-height: 100upx;
	padding: 0 1%;
	background-color: #f2f2f2;
	display: flex;
	position: fixed;
	z-index: 20;
	bottom: 0;
	.voice,.more{
		flex-shrink: 0;
		width: 90upx;
		height: 100upx;
		display: flex;
		justify-content: center;
		align-items: center;
	}
	.send{
		//H5发送按钮左边距
		/* #ifdef H5 */
		margin-left: 20upx;
		/* #endif */
		flex-shrink: 0;
		width: 100upx;
		height: 100upx;
		display: flex;
		align-items: center;
		.btn{
			width: 90upx;
			height: 56upx;
			display: flex;
			justify-content: center;
			align-items: center;
			background:linear-gradient(to right,#5fb878,#5fb878);
			color: #fff;
			border-radius: 6upx;
			font-size: 24upx;
		}
	}
	.textbox{
		width: 100%;
		min-height: 70upx;
		margin-top: 15upx;
		.voice-mode{
			width: calc(100% - 2upx);
			height: 68upx;
			border-radius: 70upx;
			border:solid 1upx #cdcdcd;
			display: flex;
			justify-content: center;
			align-items: center;
			font-size: 28upx;
			background-color: #fff;
			color: #555;
			&.recording{
				background-color: #e5e5e5;
			}
		}
		.text-mode{
			width: 100%;
			min-height: 70upx;
			display: flex;
			background-color: #fff;
			border-radius: 40upx;
			.box{
				width: 100%;
				padding-left: 30upx;
				min-height: 70upx;
				display: flex;
				align-items: center;
				textarea{
					width: 100%;
				}
			}
			.em{
				flex-shrink: 0;
				width: 80upx;
				height: 70upx;
				display: flex;
				justify-content: center;
				align-items: center;
			}
		}
	}
}
.record{
	width: 40vw;
	height: 40vw;
	position: fixed;
	top: 55%;
	left: 30%;
	background-color: rgba(0,0,0,.6);
	border-radius: 20upx;
	.ing{
		width: 100%;
		height: 30vw;
		display: flex;
		justify-content: center;
		align-items: center;
		@keyframes volatility {
			0% {background-position: 0% 130%;}
			20% {background-position: 0% 150%;}
			30% {background-position: 0% 155%;}
			40% {background-position: 0% 150%;}
			50% {background-position: 0% 145%;}
			70% {background-position: 0% 150%;}
			80% {background-position: 0% 155%;}
			90% {background-position: 0% 140%;}
			100% {background-position: 0% 135%;}
		}
		.icon{
			background-image:linear-gradient(to bottom,#f09b37,#fff 50%); 
			background-size:100% 200%;
			animation: volatility 1.5s ease-in-out -1.5s infinite alternate;
			-webkit-background-clip:text; 
			-webkit-text-fill-color:transparent; 
			font-size: 150upx;
			color: #f09b37;
		}
	}
	.cancel{
		width: 100%;
		height: 30vw;
		display: flex;
		justify-content: center;
		align-items: center;
		.icon{
			color: #fff;
			font-size: 150upx;
		}
	}
	.tis{
		width: 100%;
		height: 10vw;
		display: flex;
		justify-content: center;
		font-size: 28upx;
		color: #fff;
		&.change{
			color: #f09b37;
		}
	}
}

.content{
	width: 100%;
	.msg-list{
		width: 96%;
		padding: 0 2%;
		position: absolute;
		top: 0;
		bottom: 100upx;
		.row{
			&:first-child{
				margin-top: 0;
			}
			padding: 20upx 0;
			.my .left,.other .right{
				width: 100%;
				display: flex;
				.bubble{
					max-width: 62%;
					min-height: 50upx;
					border-radius: 10upx;
					padding: 15upx 20upx;
					display: flex;
					align-items: center;
					font-size: 32upx;
					word-break: break-word;
					&.img{
						// background-color: transparent;
						padding:5px;
						overflow: hidden;
						max-width: 62%;
						/* #ifdef H5 */
						height:auto;
						/*  #endif  */
						image{
							width: 100%;
							/* #ifdef H5 */
							height:auto;
							/*  #endif  */
							// max-height: 200upx;
						}
					}
					&.voice{
						.icon{
							font-size: 40upx;
							display: flex;
							align-items: center;
						}
						.icon:after
						{
							content:" ";
							width: 53upx;
							height: 53upx;
							border-radius: 100%;
							position: absolute;
							box-sizing: border-box;
						}
						.length{
							font-size: 28upx;
						}
					}
				}
			}
			.my .right,.other .left{
				flex-shrink: 0;
				width: 80upx;
				height: 80upx;
				image{
					width: 80upx;
					height: 80upx;
					border-radius: 10upx;
				}
			}
			.other .left{
				image{
					margin-top: 10upx;
				}
			}
			.my{
				width: 100%;
				display: flex;
				justify-content: flex-end;
				.left{
					min-height: 80upx;
					
					align-items: center;
					justify-content: flex-end;
					.bubble{
						background-color: #5FB878;
						color: #fff;
						&.voice{
							.icon{
								color: #fff;
							}
							.length{
								margin-right: 20upx;
							}
						}
						&.play{
							@keyframes my-play {
								0% {
									transform: translateX(80%);
								}
								100% {
									transform: translateX(0%);
								}
							}
							.icon:after
							{
								border-left: solid 10upx rgba(240,108,122,.5);
								animation: my-play 1s linear infinite;
							}
						}
					}
				}
				.right{
					margin-left: 15upx;
				}
			}
			.other{
				width: 100%;
				display: flex;
				.left{
					margin-right: 15upx;
				}
				.right{
					flex-wrap: wrap;
					.username{
						width: 100%;
						height: 45upx;
						font-size: 24upx;
						color: #999;
						display: flex;
						.name{
							margin-right: 50upx;
						}
					}
					.bubble{
						background-color: #f1f1f1;
						color: #333;
						&.voice{
							.icon{
								color: #333;
								
							}
							.length{
								margin-left: 20upx;
							}
						}
						&.play{
							@keyframes other-play {
								0% {
									transform: translateX(-80%);
								}
								100% {
									transform: translateX(0%);
								}
							}
							.icon:after
							{
								border-right: solid 10upx rgba(255,255,255,.8);
								
								animation: other-play 1s linear infinite;
							}
						}
					}
				}
			}
		}
	}
}
</style>
